
#include "Colors.h"

bool Colors::init()
{
	if (!LearnShader::init())	return false;
	std::cout << getChapterName().c_str() << "::" << getNodeName().c_str() << "::init" << std::endl;

	depthEnable();

	m_pCamera = ShaderCamera::create();
	m_pLamp = createLampWithDefaultPath();
	CREATE_SHADER_VERTEX_DATA(pLightData, Dataset_Vertices_Cube);
	pLightData->setVertexSize(3);
	pLightData->pushVertexAttrib(3, 0);
	m_pLight = ShaderBuffer::create(pLightData);
	
	m_pProgram = createProgramWithDefaultPath();
	CREATE_SHADER_VERTEX_DATA(pVertexData, Dataset_Vertices_Cube_Coord);
	pVertexData->setVertexSize(5);
	pVertexData->pushVertexAttrib(3, 0);
	m_pVertex = ShaderBuffer::create( pVertexData);

	return true;
}

void Colors::release()
{

}

void Colors::update(float dt)
{
	m_pCamera->update(dt);

	glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

	updateBuffer(dt);
	updateLight(dt);
	swapBuffers();
}

void Colors::updateLight(float dt)
{
	auto program = m_pLamp;
	auto vertex = m_pLight;
	auto camera = m_pCamera;
	program->use();
	vertex->bindingVertexArray();

	glm::mat4 model;
	glm::mat4 view = camera->getLookAt();
	glm::mat4 projection;
	model = glm::translate(model, glm::vec3(1.2f, 1.0f, 2.0f));
	model = glm::scale(model, glm::vec3(0.2f));
	projection = glm::perspective(45.0f, (GLfloat)WINDOWS_W / (GLfloat)WINDOWS_H, 0.1f, 100.0f);

	GLint modelLoc = glGetUniformLocation(program->getProgram(), "model");
	GLint viewLoc = glGetUniformLocation(program->getProgram(), "view");
	GLint projLoc = glGetUniformLocation(program->getProgram(), "projection");
	glUniformMatrix4fv(modelLoc, 1, GL_FALSE, glm::value_ptr(model));
	glUniformMatrix4fv(viewLoc, 1, GL_FALSE, glm::value_ptr(view));
	glUniformMatrix4fv(projLoc, 1, GL_FALSE, glm::value_ptr(projection));

	vertex->draw(36);
	vertex->cleanVertexArray();
}

void Colors::updateBuffer(float dt)
{
	auto program = m_pProgram;
	auto vertex = m_pVertex;
	auto camera = m_pCamera;

	program->use();
	GLint objectColorLoc = glGetUniformLocation(program->getProgram(), "objectColor");
	GLint lightColorLoc = glGetUniformLocation(program->getProgram(), "lightColor");
	glUniform3f(objectColorLoc, 1.0f, 0.5f, 0.31f);
	glUniform3f(lightColorLoc, 1.0f, 1.0f, 1.0f);
	vertex->bindingVertexArray();

	glm::mat4 model;
	glm::mat4 view;
	glm::mat4 projection;
	view = camera->getLookAt();
	model = glm::translate(model, glm::vec3(0.0f, 0.0f, 0.0f));
	model = glm::rotate(model, 20.0f, glm::vec3(1.0f, 0.3f, 0.5f));
	projection = glm::perspective(45.0f, (GLfloat)WINDOWS_W / (GLfloat)WINDOWS_H, 0.1f, 100.0f);

	GLint modelLoc = glGetUniformLocation(program->getProgram(), "model");
	GLint viewLoc = glGetUniformLocation(program->getProgram(), "view");
	GLint projLoc = glGetUniformLocation(program->getProgram(), "projection");
	glUniformMatrix4fv(modelLoc, 1, GL_FALSE, glm::value_ptr(model));
	glUniformMatrix4fv(viewLoc, 1, GL_FALSE, glm::value_ptr(view));
	glUniformMatrix4fv(projLoc, 1, GL_FALSE, glm::value_ptr(projection));
	
	vertex->draw(36);
	vertex->cleanVertexArray();
}

void Colors::keyBoardRelease(int key, int modes)
{
	m_pCamera->setCameraActionWithkeyBoard(key, modes, false);
}

void Colors::keyBoardPress(int key, int modes)
{
	m_pCamera->setCameraActionWithkeyBoard(key, modes, true);
}

